home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 19
/
CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso
/
CUCD
/
Online
/
Apache
/
cgi-bin
/
rx-gate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-11
|
7KB
|
266 lines
/* `
* gcc -o rx-gate rx-gate.c -O
*
* CGI Gateway to Rexx scripts. Due to the way Rexx scripts work, they don't
* inherit local variables from the httpd that spawned them. This C program
* does inhereit them, and makes the available via a Rexx port. It launches
* the script with the cgi port as the scripts default port.
*
* Invoke this with the script name to use.
*
* Copyright © 1994, Mike Meyer, modified by Jeff Shepherd to use with Apache
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <exec/types.h>
#include <dos/dos.h>
#include <rexx/storage.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/rexxsyslib.h>
#define MAXVAR 256
#define STDOUT 1
struct RxsLib *RexxSysBase ;
struct MsgPort *port ;
#define dead(x) return corpse(x,NULL,NULL)
int corpse(char *, char *, char *) ;
char line[1024];
int main(int argc, char **argv) {
char *value, command[MAXVAR], port_name[20];
char error_msg[MAXVAR];
char tempstdoutname[24], tempstdinname[29];
char *com;
BPTR tempstdout, oldstdout, tempstdin, oldstdin;
FILE *fi;
char *cmdline = NULL;
int len;
struct RexxMsg *msg ;
struct MsgPort *rexxport ;
int i;
int exit_status = 0;
RexxSysBase = NULL ;
port = NULL ;
#ifdef DEBUG
puts("Content-type: text/plain\n");
#endif
/* Get the Rexx library */
if ((RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 0)) == NULL)
dead("Can't open rexx library") ;
/* Get a message port */
sprintf(port_name, "CGI-PORT-%lx", (ULONG)FindTask(NULL));
/* temporary files for stdin and stdout */
sprintf(tempstdoutname, "t:CGI-PORT-%lx", (ULONG)FindTask(NULL));
sprintf(tempstdinname, "t:CGI-PORT-%lx-stdin", (ULONG)FindTask(NULL));
Forbid() ;
if (!FindPort(port_name)) port = CreatePort(port_name, 0) ;
Permit() ;
if (port == NULL) /* BAD news */
dead("Can't create Rexx port") ;
/* Build the message that starts things rolling */
if ((msg = CreateRexxMsg(port, NULL, port->mp_Node.ln_Name)) == NULL)
dead("Can't create rexx message") ;
/* Make one big command line to pass to the arexx script */
for (len = 1, i = 0; i < argc; i++) {
#ifdef DEBUG
printf("Argv %d = %s\n", i, argv[i]);
#endif
len += strlen(argv[i]) + 1;
}
cmdline = malloc(len);
strcpy (cmdline, argv[0]);
for (i = 1; i < argc; i++) {
strcat(cmdline, " ");
strcat(cmdline, argv[i]);
}
#ifdef DEBUG
printf("Cmdline is %s\n", cmdline);
#endif
msg->rm_Args[0] = cmdline;
if (!FillRexxMsg(msg, 1, 0)) {
free(cmdline);
DeleteRexxMsg(msg) ;
dead("Can't create rexx arguments") ;
}
free(cmdline);
msg->rm_Action = RXCOMM;
/* Since I was started by exec() my Output() is bogus but stdout
* is the socket, I will set my Output() to a temp file
* Also redirect stdin to a temp file since Input() is also the socket
*/
fi = fopen(tempstdinname, "w");
if (fi) {
while(fgets(line, 1024, stdin))
fprintf(fi,"%s",line);
fclose(fi);
}
tempstdout = Open(tempstdoutname, MODE_NEWFILE);
tempstdin = Open(tempstdinname, MODE_OLDFILE);
oldstdout = SelectOutput(tempstdout);
oldstdin = SelectInput(tempstdin);
/* Go! */
Forbid();
if ((rexxport = FindPort(RXSDIR)))
PutMsg(rexxport, (struct Message *) msg) ;
Permit();
if (!rexxport) {
ClearRexxMsg(msg, 1);
DeleteRexxMsg(msg);
SelectOutput(oldstdout);
SelectOutput(oldstdin);
Close(tempstdout);
Close(tempstdin);
remove(tempstdinname);
remove(tempstdoutname);
dead("Can't find rexx port");
}
/* must redirect Arexx output to file because stdin is a socket */
/* Ok, now we just wait for the message to come back... */
for (;;) {
WaitPort(port) ;
msg = (struct RexxMsg *) GetMsg(port) ;
if (msg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) break ;
/* That wasn't the reply, so we have a command */
strcpy(command, msg->rm_Args[0]) ;
#ifdef DEBUG
printf("Command %s\n", command);
#endif
com = strtok(command, " \t") ;
/* if it was getvar, handle it */
if (!stricmp(com , "getvar")) {
char *tok;
/* Doing getvar */
tok = strtok(NULL, " \t");
if ((value = getenv(tok)) == NULL)
value = "";
msg->rm_Result1 = 0 ;
if (!(msg->rm_Action & RXFF_RESULT))
msg->rm_Result2 = strlen(value) ;
else msg->rm_Result2 =
(LONG) CreateArgstring(value,
strlen(value)) ;
}
else {
#ifdef DEBUG
printf("Bad token %s\n", com);
#endif
msg->rm_Result1 = 10 ;
msg->rm_Result2 = 11 ;
exit_status = 1;
sprintf(error_msg, "Rexx error: #%ld", msg->rm_Result2) ;
}
ReplyMsg((struct Message *) msg) ;
}
ClearRexxMsg(msg, 1) ;
DeleteRexxMsg(msg) ;
Close(tempstdout);
Close(tempstdin);
/* echo the contents of the file to the socket */
SelectOutput(oldstdout);
SelectInput(oldstdin);
/* only print the contents of the file if the exit status is 0 */
if (exit_status == 0) {
fi = fopen(tempstdoutname, "r");
if (fi) {
while(fgets(line, 1024, fi))
printf("%s", line);
fclose(fi);
}
remove(tempstdinname);
remove(tempstdoutname);
dead(NULL);
}
else
return corpse(error_msg, tempstdinname, tempstdoutname);
}
int
corpse(char *mesg, char *stdinfi, char *stdoutfi) {
char *program_name ;
#ifdef DEBUG
printf("mesg is %s, stdinfi is %s, stdoutfi is %s\n", mesg, stdinfi, stdoutfi);
#endif
if (mesg) {
if ((program_name = getenv("SERVER_NAME")) == NULL)
program_name = "NOT CONFIGURED" ;
printf("Content-type: text/html\n\n"
"<HTML><HEAD><TITLE>Rexx Gateway error</TITLE></HEAD><BODY>\n"
"<h1>%s</h1>\nPlease contact the %s server admin.\n",
mesg, program_name) ;
}
if (stdinfi) {
char line[1024];
FILE *fi;
fi = fopen(stdinfi, "r");
if (fi) {
if (!mesg)
puts("Content-type: text/html\n");
puts("<HR><h1>STDIN</h1>");
puts("<CODE>");
while(fgets(line,1024,fi))
printf("%s",line);
fclose(fi);
puts("</CODE>");
}
remove(stdinfi);
}
if (stdoutfi) {
char line[1024];
FILE *fi;
fi = fopen(stdoutfi, "r");
if (fi) {
puts("<HR><h1>STDOUT</h1>");
puts("<CODE>");
while(fgets(line,1024,fi))
printf("%s",line);
fclose(fi);
puts("</CODE>");
}
remove(stdoutfi);
}
if (mesg || stdinfi || stdoutfi)
puts("</HTML>");
if (port) {
FreeSignal((long) (port->mp_SigBit)) ;
RemPort(port) ;
DeletePort(port) ;
}
if (RexxSysBase)
CloseLibrary((struct Library *)RexxSysBase) ;
return 0 ;
}